package com.wyh.service.serviceImpl.groupOne.organization;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wyh.common.exception.CustomException;
import com.wyh.common.utils.MasterDataRedisCache;

import com.wyh.domain.dto.gfive.LoginUser;
import com.wyh.domain.po.groupOne.MasterDataUser;
import com.wyh.domain.po.groupOne.organization.MasterDataOrganization;
import com.wyh.domain.po.groupOne.projectabout.ProjectPO;
import com.wyh.domain.vo.groupOne.utils.MasterDataTreeNode;
import com.wyh.domain.vo.groupOne.utils.TreeSearch;
import com.wyh.domain.vo.groupOne.utils.TreeUtils.MasterDataDepartmentTreeUtils;
import com.wyh.mapper.groupOne.organization.MasterDataOrganizationMapper;
import com.wyh.service.groupOne.organization.MasterDataOrganizationService;
import com.wyh.service.serviceImpl.groupOne.threemeterAbout.threemeterTree.MasterDataTreeGenerateMasterData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.IntStream;

import static com.wyh.common.enums.ResultCodeEnum.*;

@Service
public class MasterDataOrganizationServiceImpl implements MasterDataOrganizationService {

    @Autowired
    private MasterDataOrganizationMapper masterDataOrganizationMapper;

    @Autowired
    private MasterDataRedisCache masterDataRedisCache;

    @Autowired
    private MasterDataTreeGenerateMasterData masterDataTreeGenerate;

    @Autowired
    private MasterDataDepartmentTreeUtils masterDataDepartmentTreeUtils;

    // 获取当前登录的用户的id的方法
    public Integer getUserId() {
        UsernamePasswordAuthenticationToken authentication =
                (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        Integer userid = loginUser.getUser().getId();
        return userid;
    }

    // 生成组织菜单树的业务方法
    @Override
    public List<MasterDataTreeNode> generateOrganizationTree() {
        List<MasterDataTreeNode> tree = masterDataTreeGenerate.generateOrganizationOnlyTree();
        return tree;
    }

    // 添加组织的业务方法
    @Override
    @Transactional
    public boolean addOrganization(MasterDataOrganization masterDataOrganization) {
        if (masterDataOrganization != null) {
            // 查询是否有一样的统一信用编码
            MasterDataOrganization masterDataOrganizationByCreditCode = masterDataOrganizationMapper.selectOrganizationByCreditCode(masterDataOrganization.getCreditcode());
            if (masterDataOrganizationByCreditCode != null) {
                throw new CustomException(CREDITCODE_HAS_EXISTED);
            }
            boolean isAddSuccess = masterDataOrganizationMapper.insertOrganization(masterDataOrganization);
            if (!isAddSuccess) {
                throw new CustomException(SYSTEM_ERROR);
            }
            // 删除redis的缓存
            masterDataRedisCache.deleteObject("wyh:MasterDataDepartmentTree:" + getUserId());

            // 更新redis中的树
            masterDataDepartmentTreeUtils.updateDepartmentTree(getUserId());
            return true;
        } else {
            throw new CustomException(ORGANIZATION_ADD_NULL_ERROR);
        }
    }

    // 循环查询组织的上级组织是否存在，存在就返回这个组织
    private MasterDataOrganization getTopOrganization(Integer superiorid) {
        // 查询当前这个上级组织是否存在
        MasterDataOrganization currentMasterDataOrganization = masterDataOrganizationMapper.selectByOid(superiorid);
        // 不存在就返回null
        if (currentMasterDataOrganization == null) {
            return null;
        }
        // 递归查询上级组织
        while (currentMasterDataOrganization.getSuperiorid() != 0) {
            currentMasterDataOrganization = masterDataOrganizationMapper.selectByOid(currentMasterDataOrganization.getSuperiorid());
            if (currentMasterDataOrganization == null) {
                throw new CustomException(ORGANIZATION_NULL_ERROR);
            }
        }
        return currentMasterDataOrganization;
    }

    // 根据组织的id查询一个组织信息的业务方法
    @Override
    public MasterDataOrganization findOrganizationById(Integer id) {
        if (id == null) {
            throw new CustomException(PARAM_ERROR);
        }
        // 获取当前用户所属的组织 ID
        MasterDataOrganization userMasterDataOrganization = masterDataOrganizationMapper.selectOrganizationBaseByUserId(getUserId());
        // 获取所有下级组织 ID 列表
        List<MasterDataOrganization> allMasterDataOrganizations = masterDataOrganizationMapper.selectAll();
        List<Integer> subordinateIds = getSubordinateIds(allMasterDataOrganizations, userMasterDataOrganization.getId());
        // 检查所请求的组织 ID 是否是当前用户所属组织或其下级组织
        if (!id.equals(userMasterDataOrganization.getId()) && !subordinateIds.contains(id)) {
            throw new CustomException(ORGANIZATION_AUTHORITY_ERROR);
        }
        // 获取组织信息
        MasterDataOrganization masterDataOrganization = masterDataOrganizationMapper.selectByOid(id);
        // 获取上级组织的名称
        if (masterDataOrganization.getSuperiorid() != null && masterDataOrganization.getSuperiorid() != 0) {
            MasterDataOrganization superiorMasterDataOrganization = masterDataOrganizationMapper.selectByOid(masterDataOrganization.getSuperiorid());
            masterDataOrganization.setSuperiorName(superiorMasterDataOrganization.getName());
        }
        return masterDataOrganization;
    }

    // 获取所有下级组织 ID 的方法
    private List<Integer> getSubordinateIds(List<MasterDataOrganization> masterDataOrganizationList, Integer sid) {
        List<Integer> result = new ArrayList<>();
        for (MasterDataOrganization o : masterDataOrganizationList) {
            if (o.getSuperiorid() != null && o.getSuperiorid().equals(sid)) {
                result.add(o.getId());
                result.addAll(getSubordinateIds(masterDataOrganizationList, o.getId()));
            }
        }
        return result;
    }

    // 编辑组织的业务方法
    @Override
    @Transactional
    public boolean editOrganization(MasterDataOrganization masterDataOrganization) {
        if (masterDataOrganization != null) {
            // 判断当前组织的状态，如果是停用就不执行修改操作
            Integer state = masterDataOrganizationMapper.selectStateByOid(masterDataOrganization.getId());
            if (state == 0) {
                throw new CustomException(ORGANIZATION_STATE_ERROR);
            }
            // 查询是否有一样的统一信用编码
            MasterDataOrganization masterDataOrganizationByCreditCode = masterDataOrganizationMapper.selectOrganizationByCreditCode(masterDataOrganization.getCreditcode());
            if (masterDataOrganizationByCreditCode != null) {
                throw new CustomException(CREDITCODE_HAS_EXISTED);
            }
            boolean isUpdateSuccess = masterDataOrganizationMapper.updateOrganization(masterDataOrganization);
            if (!isUpdateSuccess) {
                throw new CustomException(SYSTEM_ERROR);
            }

            masterDataRedisCache.deleteObject("wyh:MasterDataDepartmentTree:" + getUserId());

            // 更新redis中的树
            masterDataDepartmentTreeUtils.updateDepartmentTree(getUserId());
            return true;
        } else {
            throw new CustomException(ORGANIZATION_UPDATE_NULL_ERROR);
        }
    }

    // 删除一个组织的业务方法
    @Override
    @Transactional
    public boolean removeOrganization(Integer id) {
        if (id == null) {
            throw new CustomException(PARAM_ERROR);
        }
        // 判断删除的组织下有没有下级组织，先根据id查出该组织
        List<MasterDataOrganization> masterDataOrganizations = masterDataOrganizationMapper.selectBySid(id);
        if (!masterDataOrganizations.isEmpty()) {
            throw new CustomException(ORGANIZATION_REMOVE_REMAIN_ERROR);
        }
        // 判断该组织有没有关联的项目，如果有就不能删除
        ProjectPO project = masterDataOrganizationMapper.selectProjectByOid(id);
        if (project != null) {
            throw new CustomException(ORGANIZATION_REMOVE_REMAIN_PROJECT_ERROR);
        }
        boolean isRemoveSuccess = masterDataOrganizationMapper.deleteOrganization(id);
        if (!isRemoveSuccess) {
            throw new CustomException(ORGANIZATION_REMOVE_ERROR);
        }
        masterDataRedisCache.deleteObject("wyh:MasterDataDepartmentTree:" + getUserId());

        // 更新redis中的树
        masterDataDepartmentTreeUtils.updateDepartmentTree(getUserId());
        return true;
    }

    // 根据组织id查询组织下以及下级组织下的所有用户的业务方法
    @Override
    public PageInfo<MasterDataUser> findUsers(Integer oid, int pageNum, int pageSize) {
        // id为空，返回参数错误
        if (oid == null) {
            throw new CustomException(PARAM_ERROR);
        }

        // 使用迭代的方法来遍历所有的用户
        List<MasterDataUser> masterDataUserList = new ArrayList<>();
        List<Integer> orgQueue = new ArrayList<>();
        orgQueue.add(oid);
        while (!orgQueue.isEmpty()) {
            Integer currentOid = orgQueue.remove(0);
            List<MasterDataUser> masterDataUsers = masterDataOrganizationMapper.selectUserByOid(currentOid);
            if (masterDataUsers != null && !masterDataUsers.isEmpty()) {
                masterDataUserList.addAll(masterDataUsers);
            }
            List<MasterDataOrganization> subMasterDataOrganizations = masterDataOrganizationMapper.selectBySid(currentOid);
            for (MasterDataOrganization subOrg : subMasterDataOrganizations) {
                orgQueue.add(subOrg.getId());
            }
        }

        // 合并具有相同ID的用户
        List<MasterDataUser> mergedMasterDataUsers = mergeUsers(masterDataUserList);

        if (mergedMasterDataUsers.isEmpty()) {
            throw new CustomException(ORGANIZATION_USER_ERROR);
        }

        // 分页处理
        return getPageInfo(mergedMasterDataUsers, pageNum, pageSize);
    }

    // 合并用户列表中具有相同ID的用户
    private List<MasterDataUser> mergeUsers(List<MasterDataUser> masterDataUserList) {
        Map<Integer, MasterDataUser> userMap = new HashMap<>();
        for (MasterDataUser masterDataUser : masterDataUserList) {
            Integer id = masterDataUser.getId();
            if (userMap.containsKey(id)) {
                MasterDataUser existingMasterDataUser = userMap.get(id);

                // 初始化 rolename 为一个空字符串以防止 NullPointerException
                String existingRolesString = existingMasterDataUser.getRolename() != null ? existingMasterDataUser.getRolename() : "";
                String newRolesString = masterDataUser.getRolename() != null ? masterDataUser.getRolename() : "";

                List<String> existingRoles = new ArrayList<>(Arrays.asList(existingRolesString.split(";")));
                List<String> newRoles = Arrays.asList(newRolesString.split(";"));

                Set<String> roleSet = new HashSet<>(existingRoles);
                roleSet.addAll(newRoles);

                existingMasterDataUser.setRolename(String.join(";", roleSet));
            } else {
                // 确保 rolename 字段不是 null
                if (masterDataUser.getRolename() == null) {
                    masterDataUser.setRolename("");
                }
                userMap.put(id, masterDataUser);
            }
        }
        return new ArrayList<>(userMap.values());
    }


    // 分页处理方法
    private PageInfo<MasterDataUser> getPageInfo(List<MasterDataUser> masterDataUserList, int pageNum, int pageSize) {
        int total = masterDataUserList.size();
        int fromIndex = Math.min((pageNum - 1) * pageSize, total);
        int toIndex = Math.min(fromIndex + pageSize, total);

        List<MasterDataUser> pageList = masterDataUserList.subList(fromIndex, toIndex);

        PageInfo<MasterDataUser> pageInfo = new PageInfo<>(pageList);
        pageInfo.setPageNum(pageNum);
        pageInfo.setPageSize(pageSize);
        pageInfo.setTotal(total);
        pageInfo.setPages((int) Math.ceil((double) total / pageSize));
        pageInfo.setSize(pageList.size());
        pageInfo.setStartRow(fromIndex);
        pageInfo.setEndRow(toIndex - 1);
        pageInfo.setIsFirstPage(pageNum == 1);
        pageInfo.setIsLastPage(pageNum == pageInfo.getPages());
        pageInfo.setHasPreviousPage(pageNum > 1);
        pageInfo.setHasNextPage(pageNum < pageInfo.getPages());

        int navigatePages = 8;
        int[] navigatePageNums = new int[Math.min(navigatePages, pageInfo.getPages())];
        for (int i = 0; i < navigatePageNums.length; i++) {
            navigatePageNums[i] = pageNum - (navigatePageNums.length / 2) + i;
            if (navigatePageNums[i] < 1) navigatePageNums[i] = i + 1;
            if (navigatePageNums[i] > pageInfo.getPages()) navigatePageNums[i] = pageInfo.getPages() - navigatePageNums.length + i + 1;
        }
        pageInfo.setNavigatePages(navigatePages);
        pageInfo.setNavigatepageNums(navigatePageNums);

        return pageInfo;
    }


    // 模糊查询组织的业务方法
    @Override
    public List<MasterDataTreeNode> searchOrganizationTree(String keyword) {
        // 获取树
        List<MasterDataTreeNode> tree = generateOrganizationTree();
        MasterDataTreeNode masterDataTreeNode = tree.get(0);
        List<MasterDataTreeNode> searchTree = TreeSearch.searchTree(masterDataTreeNode, keyword);
        return searchTree;
    }
}
